home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
image
/
acl30bsx.zip
/
ACL.CPP
next >
Wrap
C/C++ Source or Header
|
1996-06-25
|
18KB
|
640 lines
/*
* Copyright (c) 1995, 1996 Branislav L. Slantchev
* A Product of Silicon Creations, Inc.
*
* This source is distributed under the terms and conditions of the
* GNU General Library License. A copy of the license is included with
* this distrbiution (see the file 'Copying.Pbl').
*
* Contact: 73023.262@compuserve.com
*/
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "sys/_defs.h"
#include "sys/portable.h"
#include "fail.h"
#include "getopt.h"
#include "filesys.h"
#define __VERSION__ "v3.0b"
typedef struct{
ushort size; // data size in data file
short lines; // # lines in the animation
ushort delay; // delay factor b/n steps, 0=static
short column; // start at column#
long offset; // offset of data into the data file
char extra[4]; // spare bytes
} ACL_INDEX;
// The header for the data files (.KDT)
typedef struct{
char name[80]; // name of the file, ASCIIZ
char idString[10]; // 10 bytes id string (not ASCIIZ)
short numRecs; // number of records stored
char __rsrvd[58]; // reserved space
} KAF_HEADER;
// The local header in the data file (.KDT)
typedef struct{
char name[26]; // name of the sequence
ushort dataSize; // length of the record (excluding the header)
short numLines; // number of lines to animate
ushort speed; // default animation speed (0 == static)
short maxChars; // maximum line length (0 == ignore)
char __rsrvd[6];
} KAF_RECORD;
enum Cmds {cmAdd, cmDelete, cmExport, cmShow, cmList, cmEdit, cmMerge, cmCopy};
void print_help();
void print_banner();
void add(char*, char*, Boolean, Boolean, int, int);
void list(char*);
void export(char*, int);
void erase(char*, int);
void show(char*, int, int, int, int);
void edit(char*, int, int, int, Boolean);
void merge(char*, char*);
void copy(char*, char*);
int
main(int argc, char *argv[])
{
Cmds Command;
int opt, nPrompt = -1, nDelay = 80, nColumn = 1, nLine = 24;
Boolean bAsk = False, bCompat = False;
char dataPath[80], *fileSpec = 0;
strcpy(dataPath, "a.adt");
print_banner();
if( 1 == argc || argv[1][0] == '?' || argv[1][1] == '?' ){
print_help();
return 1;
}
switch( tolower(argv[1][0]) ){
case 'a': Command = cmAdd; break;
case 'd': Command = cmDelete; break;
case 'x': Command = cmExport; break;
case 's': Command = cmShow; break;
case 'l': Command = cmList; break;
case 'e': Command = cmEdit; break;
case 'm': Command = cmMerge; break;
case 'k': Command = cmCopy; break;
default : fail("Unknown mode: %c\n", argv[1][0]);
}
while( EOF != (opt = getopt(argc - 1, &argv[1], "io:#:rp:c:f:y:")) ){
switch( tolower(opt) ){
case 'i': bAsk = True; break;
case 'o': file_chext(dataPath, optarg, ".adt"); break;
case '#': nPrompt = atoi(optarg); break;
case 'r': bCompat = True; break;
case 'p': nDelay = atoi(optarg); break;
case 'c': nColumn = atoi(optarg); break;
case 'f': fileSpec = optarg; break;
case 'y': nLine = atoi(optarg); break;
}
}
switch( Command ){
case cmAdd:
add(dataPath, fileSpec, bAsk, bCompat, nDelay, nColumn);
break;
case cmList : list(dataPath); break;
case cmExport: export(dataPath, nPrompt); break;
case cmDelete: erase(dataPath, nPrompt); break;
case cmShow : show(dataPath, nPrompt, nDelay, nColumn, nLine); break;
case cmEdit : edit(dataPath, nPrompt, nDelay, nColumn, bAsk); break;
case cmMerge : merge(dataPath, fileSpec); break;
case cmCopy : copy(dataPath, fileSpec); break;
}
return 0;
}
void
print_help()
{
puts("Usage : ACL <command> -<switch> [-<switch>...] -f<filespec>");
puts("Examples: ACL a -f *.ans -r, ACL l -o archive, ACL -x -#12\n");
puts("<Commands>");
puts(" a: Add files to archive d: Delete records from archive");
puts(" l: List records in archive s: Show animated record");
puts(" x: Export records to file e: Edit record parameters");
puts(" m: Merge two data files k: Copy records from a KAF file");
puts("<Switches>");
puts(" f: Specify files to add i: Interactive mode");
puts(" r: Add RemoteAccess animations p: Specify millisecond delay");
puts(" c: Specify starting column #: Specify record number");
puts(" o: Use different archive name y: Specify row for display");
puts("\nWhen adding, merging or copying, the '-f fileSpec' switch is required.");
puts("The default archive is named 'a.*', use '-o altname' to change.");
puts("Use '-i' when adding or editing to specify column and delay.");
}
void
print_banner()
{
printf("ACL %s Copyright (c) 1995-1996 Branislav L. Slantchev. %s\n"
"A product of Silicon Creations, Inc. (part of the PB-GNU Project)"
"\n\n", __VERSION__, __DATE__);
}
void
add(char *data, char *spec, Boolean ask, Boolean compat, int nDelay, int column)
{
char index[80], buf[1024], base[80], path[80];
ACL_INDEX rec;
ushort dataLen;
FILE *in, *dat, *idx;
int done, total = 0;
zDosFile ffblk;
if( !spec ) fail("No '-f filespec' specified with 'add' command\n");
file_chext(index, data, ".aix");
strcpy(base, file_dirspec(spec));
dat = fopen(data, "a+b");
if( !dat ) fail("unable to open data file '%s'\n", data);
idx = fopen(index, "a+b");
if( !idx ) fail("unable to open the index file '%s'\n", index);
fseek(dat, 0L, SEEK_END);
fseek(idx, 0L, SEEK_END);
rec.column = column;
rec.delay = nDelay;
memset(rec.extra, 0, sizeof(rec.extra));
done = FindFirst(spec, 0, &ffblk);
while( !done ){
strcat(strcpy(path, base), ffblk.name);
printf("\nadding %s...", path);
in = fopen(path, "rt");
if( in ){
rec.lines = rec.size = 0;
rec.offset = ftell(dat);
if( compat ){
fgets(buf, sizeof(buf), in);
sscanf(buf, "%*d %*s %*d %d", &rec.column);
}
fgets(buf, sizeof(buf), in);
while( !feof(in) ){
char *p = buf + strlen(buf) - 1;
if( '\n' == *p ) *p = EOS;
dataLen = strlen(buf);
rec.lines++;
rec.size += dataLen + sizeof(ushort);
fwrite(&dataLen, sizeof(ushort), 1, dat);
fwrite(buf, 1, dataLen, dat);
fgets(buf, sizeof(buf), in);
}
if( ask ){
printf("\nDelay (milsecs)? "); gets(buf);
if( strlen(buf) ) rec.delay = atoi(buf);
printf("Starting column? "); gets(buf);
if( strlen(buf) ) rec.column = atoi(buf);
}
fwrite(&rec, sizeof(rec), 1, idx);
fclose(in);
printf("done (%d lines)", rec.lines);
}
total++;
done = FindNext(&ffblk);
}
printf("\n\nAdded %d records.\n", total);
fclose(dat);
fclose(idx);
if( 0 == file_size(data) ) file_remove(data);
if( 0 == file_size(index)) file_remove(index);
}
void
list(char *data)
{
char path[80];
int total = 0;
ACL_INDEX rec;
FILE *fp;
file_chext(path, data, ".aix");
fp = fopen(path, "rb");
if( fp ){
printf(" Recno Size Lines Delay Column Offset\n"
" ----- ---- ----- ----- ------ --------\n");
fread(&rec, sizeof(rec), 1, fp);
while( !feof(fp) ){
total++;
printf(" %4d %5d %5d %5d %5d %08lX\n",
total, rec.size, rec.lines, rec.delay, rec.column, rec.offset);
fread(&rec, sizeof(rec), 1, fp);
}
fclose(fp);
printf(" -----------------------------------------------\n"
" Total: %d records.\n", total);
}
}
void
export(char *data, int nPrompt)
{
char index[80], xpath[80], buf[1024];
ACL_INDEX rec;
FILE *idx, *dat, *out;
int total, start, end, exported = 0;
file_chext(index, data, ".aix");
total = (int)(file_size(index) / sizeof(ACL_INDEX));
if( 0 > nPrompt || total < nPrompt )
fail("Prompt number out of range (valid: 0 thru %d)\n", total);
idx = fopen(index, "rb");
dat = fopen(data, "rb");
if( !idx || !dat ) fail("Unable to open the data file(s)\n");
if( 0 == nPrompt ){
start = 0;
end = total;
}
else{
start = nPrompt - 1;
end = nPrompt;
}